Catalyst / admin/Strike 14.8 GB / 57.8 GB 40.0 GB free
Help Sign in

admin / Strike

public

Web-Based UK Cyber Compliance Tool with Reporting

Code Issues Pull requests Pipelines Packages Security Insights Wiki Settings
Strike / StrikeXi v3 / README.md 14397 B · main
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# StrikeXi v3 — Multi-Framework Cyber Maturity Assessment Platform

An enterprise-grade, fully containerised web application for conducting Cyber
Maturity Assessments against **multiple maturity frameworks**. It ships with the
**NCSC Cyber Assessment Framework (CAF)** and the **UK Cyber Security &
Resilience Bill (CSRB)**. It scores weighted responses, auto-generates an
actionable remediation roadmap, derives a residual-risk view, and exports a
professional PDF report.

> **This is Version 3.** It runs alongside v1 (**:8080**) and v2 (**:8081**) on
> its own port (**:8082**), with separate containers/volumes, and adds
> everything below **without removing any v2 feature**.

---

## What's new in v3

1. **Multiple maturity frameworks** — "Start New Assessment" now begins with a
   **framework chooser** step. Pick the assessment to run, and the relevant
   questionnaire opens. Ships with:
   - **NCSC CAF** (4 objectives, 14 principles), and
   - **UK Cyber Security & Resilience Bill** (4 objectives, 8 principles
     covering scope/registration, governance, risk management, supply-chain
     duties, **24h/72h** mandatory incident reporting, operational resilience
     and regulatory cooperation).
2. **Re-assessment with retained history** — a completed assessment can be
   **revised and re-scored**. Every scoring run is snapshotted as an **immutable
   revision**, so the **original result is never lost**. The results UI and the
   **PDF** show the **previous vs new** maturity (overall and per-objective).
3. **Evidence & notes** — add **text notes** and **upload evidence files**,
   either assessment-wide or **against a specific question**. Each entry is
   **date/time-stamped with the username** and written to the **audit log**
   (`NOTE_ADDED`, `EVIDENCE_ADDED`). Evidence is listed in the results UI and
   included in the exported PDF.
4. **Future-proofed for new frameworks** — adding another framework is **pure
   data** (insert a `frameworks` row plus its objectives/principles/questions/
   remediations in the seed/DB). It appears in the chooser automatically — **no
   code changes**. The scoring, risk and PDF engines are framework-agnostic.

All **v2** capabilities are retained:

- **Self-service signup** (`user` role, profile capture, first-login MFA).
- **Admin user visibility** (Account type column + profile details).
- **Risk Assessment Summary** (UI + PDF).
- **Admin delete assessments** and **Admin Users Report** (PDF/CSV).

---

## 1. Architecture & Tech Stack

| Layer      | Technology                              | Container          |
|------------|-----------------------------------------|--------------------|
| Frontend   | HTML + CSS + vanilla JS (SPA), Nginx    | `strikexi-frontend`|
| Backend    | Python **FastAPI** + SQLAlchemy + JWT   | `strikexi-backend` |
| PDF engine | WeasyPrint (HTML/CSS → PDF, inline SVG) | (in backend)       |
| Database   | **PostgreSQL 16**                       | `strikexi-db`      |

- Orchestrated with **Docker Compose**.
- **Named volumes** (`strikexi_pgdata`, `strikexi_reports`) persist data and
  generated reports across hypervisor reboots.
- Nginx serves the SPA and reverse-proxies `/api/*` to the backend.

### Directory layout

```
strikexi/
├── docker-compose.yml
├── .env.example
├── README.md
├── db/
│   ├── init/
│   │   ├── 01_schema.sql        # frameworks, taxonomy, scores, evidence, revisions, audit log
│   │   └── 02_seed.sql          # CAF (4 obj/14 principles) + CSRB (4 obj/8 principles) frameworks
│   └── sample_caf_questions.json
├── backend/
│   ├── Dockerfile
│   ├── requirements.txt
│   └── app/
│       ├── main.py              # app, CORS, startup admin seed
│       ├── config.py
│       ├── database.py
│       ├── models.py            # SQLAlchemy ORM (frameworks, evidence, revisions)
│       ├── schemas.py           # Pydantic
│       ├── security.py          # bcrypt + JWT + audit helper
│       ├── scoring.py           # weighted scoring + remediation + revision snapshot
│       ├── risk.py              # framework-agnostic residual-risk engine
│       ├── pdf_report.py        # PDF report (donut/bars, score comparison, evidence)
│       ├── user_report.py       # admin users report (PDF/CSV)
│       ├── itsm.py              # Jira/ServiceNow adapter stubs (future-proofing)
│       └── routers/
│           ├── auth.py          # login (2-step MFA) / logout / me
│           ├── users.py         # user administration + self-service password/MFA
│           ├── frameworks.py    # list available frameworks (chooser)
│           ├── catalogue.py     # questionnaire tree (scoped by ?framework=)
│           ├── assessments.py   # CRUD, complete, rescore, evidence, revisions, PDF, ITSM
│           └── audit.py         # audit log viewer
├── frontend/
│   ├── index.html
│   ├── nginx.conf
│   ├── css/app.css
│   └── js/app.js
└── docs/
    ├── build_user_guide.py
    └── StrikeXi_User_Guide.pdf
```

---

## 2. Build & Run

```bash
cd strikexi
cp .env.example .env          # then EDIT secrets (SECRET_KEY, passwords)
docker compose up -d --build
```

Then open:

- **Web UI:** http://localhost:8082  (v3; v1 stays on :8080, v2 on :8081)
- **Default login:** `admin` / value of `ADMIN_PASSWORD` in `.env`
- **New users:** click **Create an account** on the login page (self-service)

Useful commands:

```bash
docker compose logs -f backend     # tail backend logs
docker compose ps                  # container status
docker compose down                # stop (data kept in volumes)
docker compose down -v             # stop AND wipe data volumes
```

> First boot runs `db/init/*.sql` automatically to create the schema and seed
> the CAF taxonomy, weighted questions and remediation mappings. The backend
> seeds the bcrypt-hashed admin user on startup.

---

## 3. Core Functionality

- **Questionnaire engine** — covers **all 4 CAF Objectives (A–D) and all 14
  Principles** (A1–A4, B1–B6, C1–C2, D1–D2), served as a tree from
  `/api/catalogue`. See `db/sample_caf_questions.json` for the full list.
- **Weighted scoring** (`scoring.py`) — option score × question weight, rolled
  up to principle → objective → overall (0–100). Per-principle scores are
  snapshotted in `assessment_principle_scores` for the report breakdown.
- **Remediation mapping**`remediation_mappings` links each of the 14
  principles to a **principle-specific** remediation with detailed mitigation
  guidance and a `threshold`; principles scoring below it automatically queue a
  `remediation_actions` row.
- **Save / pause / review** — assessments persist as `in_progress` or
  `completed` and are listed on the dashboard.

## 4. PDF Reporting & Roadmap

Before export the user confirms **Organisation Assessed** and **Date of
Assessment**. The PDF includes:

- Custom organisation name and date
- Overall maturity score (SVG donut) and per-objective scores (SVG bars)
- **Assessment summary / breakdown** — every assessed principle, grouped by
  objective, with score and status
- **Actionable Maturity Roadmap** — remediation steps ordered by priority, each
  referencing its Objective + Principle and giving detailed mitigation guidance

**Future-proofing:** roadmap items are modelled for ITSM export. `itsm.py`
provides a pluggable adapter interface with Jira/ServiceNow stubs, exposed via
`POST /api/assessments/{id}/push-itsm?system=jira`.

## 5. Security, Users & Auditing

- **Auth:** username/password login; bcrypt hashing; JWT bearer sessions with
  expiry. Three roles: **admin**, **assessor**, and **user** (v2 self-service).
  - **`user`** accounts (self-service signups) can only see assessments they
    create. **`admin`** sees everything; **`assessor`** sees their own.
- **Password policy (v2):** minimum 8 characters, at least one capital letter
  and at least one special character (enforced on signup, admin create, and
  self-service change).
- **First-login MFA (v2):** self-service accounts are created MFA-required and
  are routed to TOTP enrolment on their first sign-in before they can proceed.
- **User administration (admin)** — the **👥 Users** screen lets an admin:
  - **add** users (username, full name, temporary password, role),
  - **edit** users (role, enable/disable, force password change, reset
    password),
  - **delete** users (blocked for accounts that own assessments — disable
    instead), and
  - **reset** a user's MFA.
  - Guards prevent demoting/disabling/deleting the last active administrator.
- **Self-service (⚙ My Account)** — any user can **change their own password**
  and **set up / disable their own MFA**.
- **Multi-factor authentication (TOTP / RFC 6238)** — optional, compatible with
  Google Authenticator, Authy, 1Password, etc.
  - **Admin level:** mark MFA **required** for a user (forces enrolment) at
    creation or via edit, and reset a user's MFA. Required MFA can't be
    self-disabled.
  - **User level:** self-enrol from the account page (QR code + secret, confirm
    with a code).
  - Login becomes a **two-step flow** (password → 6-digit code) when MFA is on.
- **First-login hardening:** the seeded `admin` account is flagged
  *must change password*, forcing a real password to be set on first login.
  This is **self-healing** (v3): on every backend start, if the `admin` account
  still uses the default `ADMIN_PASSWORD`, the forced-password-change is
  re-armed — so the first-login admin setup reliably appears even when the data
  volume persists across a rebuild. An admin who has already set a real password
  is left untouched. (To wipe everything and start clean instead, use
  `docker compose down -v`.)
- **Audit log:** records who did what — LOGIN_SUCCESS, LOGIN_FAILED,
  LOGIN_MFA_CHALLENGE, LOGIN_MFA_FAILED, LOGOUT, PASSWORD_CHANGED,
  MFA_SETUP_BEGIN, MFA_ENABLED, MFA_DISABLED, USER_CREATED, USER_UPDATED,
  USER_DELETED, USER_MFA_RESET, plus assessment/PDF/ITSM events — each with
  timestamp, **acting username** and source IP. Viewable in the UI (admins).

---

## API Quick Reference

| Method | Path                                   | Purpose                       |
|--------|----------------------------------------|-------------------------------|
| POST   | `/api/auth/signup`                     | **(v2)** Public self-service signup (`user` role) |
| POST   | `/api/auth/login`                      | Password step (JWT or MFA challenge) |
| POST   | `/api/auth/login/mfa`                  | Verify TOTP, obtain JWT       |
| GET    | `/api/auth/me`                         | Current user profile          |
| GET    | `/api/users`                           | List users (admin)            |
| GET    | `/api/users/report.csv`                | **(v2)** Users report — CSV (admin) |
| GET    | `/api/users/report.pdf`                | **(v2)** Users report — PDF (admin) |
| POST   | `/api/users`                           | Create user (admin)           |
| PATCH  | `/api/users/{id}`                      | Update user (admin)           |
| DELETE | `/api/users/{id}`                      | Delete user (admin)           |
| POST   | `/api/users/{id}/mfa/reset`            | Reset a user's MFA (admin)    |
| POST   | `/api/users/me/password`               | Change own password           |
| POST   | `/api/users/me/mfa/setup`              | Begin own MFA enrolment       |
| POST   | `/api/users/me/mfa/confirm`            | Confirm + enable own MFA      |
| POST   | `/api/users/me/mfa/disable`            | Disable own MFA               |
| GET    | `/api/frameworks`                      | **(v3)** List available frameworks (chooser) |
| GET    | `/api/catalogue?framework={id}`        | Questionnaire tree for a framework |
| GET    | `/api/assessments`                     | List assessments              |
| POST   | `/api/assessments`                     | Create (start) assessment (`framework_id`) |
| DELETE | `/api/assessments/{id}`                | **(v2)** Delete assessment (admin) |
| GET    | `/api/assessments/{id}/risk`           | **(v2)** Risk assessment summary |
| PUT    | `/api/assessments/{id}/answers`        | Save / pause / revise answers |
| POST   | `/api/assessments/{id}/complete`       | Score + trigger remediations (revision 1) |
| POST   | `/api/assessments/{id}/rescore`        | **(v3)** Re-score (keeps original, returns prev+new) |
| GET    | `/api/assessments/{id}/revisions`      | **(v3)** Score revision history |
| GET    | `/api/assessments/{id}/evidence`       | **(v3)** List evidence/notes  |
| POST   | `/api/assessments/{id}/notes`          | **(v3)** Add a text note (audited) |
| POST   | `/api/assessments/{id}/evidence`       | **(v3)** Upload an evidence file (audited) |
| GET    | `/api/assessments/{id}/evidence/{eid}/download` | **(v3)** Download evidence file |
| GET    | `/api/assessments/{id}/roadmap`        | Ordered remediation roadmap   |
| POST   | `/api/assessments/{id}/report`         | Confirm meta + generate PDF   |
| GET    | `/api/assessments/{id}/report/download`| Download PDF                  |
| POST   | `/api/assessments/{id}/push-itsm`      | (Stub) push roadmap to ITSM   |
| GET    | `/api/audit`                           | Audit log                     |

---

## Adding a new framework (no code changes)

1. Insert a row in **`frameworks`** (`id`, `name`, `description`, `version`).
2. Insert its **`caf_objectives`** and **`caf_principles`** rows with that
   `framework_id` (the tables are generic "objective → principle" levels).
3. Insert its **`questions`** + **`answer_options`** (any scale) and
   **`remediation_suggestions`** / **`remediation_mappings`**.

The new framework then appears in the chooser automatically and works end-to-end
(questionnaire, scoring, risk, roadmap, PDF). See the **CSRB** block in
`db/init/02_seed.sql` for a complete worked example.

## Notes

- Each framework's seed is self-contained. The CAF set covers all 14 principles;
  the CSRB set covers 8 principles across its 4 objectives.
- Always change default secrets before any non-local deployment.